package org.freeone.oauth2.authorizeserver.config;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.freeone.oauth2.authorizeserver.entity.UserEntity;
import org.freeone.oauth2.authorizeserver.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collection;

/**
 * 实现AuthorizingRealm接口用户用户认证
 *
 * @author lqq
 * @date 2019年2月23日
 */
public class MyShiroRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }


    /**
     * 登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //加这一步的目的是在Post请求的时候会先进认证，然后在到请求
        if (token.getPrincipal() == null) {
            return null;
        }
        //获取用户信息
        String name = token.getPrincipal().toString();
        if (name == null) {
            return null;
        }
        //跟配置中一样查询account
        UserEntity userModel = userService.findByUserName(name);
        if (userModel == null) {
            //这里返回后会报出对应异常
            return null;
        } else {
            DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
            DefaultSessionManager sessionManager = (DefaultSessionManager) securityManager.getSessionManager();
            Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();//获取当前已登录的用户session列表
            for (Session session : sessions) {
                UserEntity users = (UserEntity) (session.getAttribute("USER_IN_SESSION"));
                if (users != null) {
                    if (userModel.getUsername().equals(users.getUsername()) && userModel.getPassword().equals(users.getPassword())) {
                        if (SecurityUtils.getSubject().getSession().getId().equals(session.getId())) {
                            break;
                        } else {
                            System.err.println(userModel.getUsername() + "已登录，移除以保存的session");
                            sessionManager.getSessionDAO().delete(session);
//                            messagingTemplate.convertAndSendToUser(username, "/queue/message", new WiselyResponse("该账号已在其他机器登陆！"));   // websocket发送消息
                        }
                    }
                }
            }


            //这里验证authenticationToken和simpleAuthenticationInfo的信息
            return new SimpleAuthenticationInfo(userModel.getUsername(), userModel.getPassword().toString(), getName());
        }
    }

}
